from typing import AsyncIterator, Awaitable

from aioredis import from_url, Redis
from dependency_injector import containers, providers


# 2. 初始化Redis连接和关闭
async def init_redis_pool(host: str, password: str, db: int = 0, port: int = 6379) -> AsyncIterator[Redis]:
    session = await from_url(
        url=f"redis://{host}", port=port, password=password, db=db, encoding="utf-8", decode_responses=True
    )
    yield session
    await session.close()


# 3. 添加 server类，实现Redis 动作，Server 依赖于 Redis
class Service(object):
    def __init__(self, redis: Redis) -> None:
        self._redis = redis

    async def set(self, key: str, value: str) -> Awaitable:
        return await self._redis.set(key, value)

    async def get(self, key: str) -> str:
        return await self._redis.get(key)


# 4. 创建一个 Container 容器，用于连接Redis并存放连接池
class Container(containers.DeclarativeContainer):
    config = providers.Configuration()
    redis_pool = providers.Resource(
        init_redis_pool,
        host=config.redis_host,
        port=config.redis_port,
        db=config.redis_db,
        password=config.redis_password,
    )
    service = providers.Factory(Service, redis=redis_pool)
